/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "S_物体.h"

#include "core/shader_line.h"
#include "底层绘图/底层绘图框架.h"
#include "底层绘图/intern/Vulkan/buffer/Vk缓存.h"

#include "面/Mesh.h"
#include "面/面.h"

#include "S_键值序列容器.h"
#include <matXX.h>



std::set<S_物体*> g物体ID;
std::set<S_骨架*> C_骨骼管理::m_骨骼容器;

static S_键值序列容器<uint32, S_物体*> g_物体容器;
static C_骨骼管理 g_骨骼容器;



static bool g_可视[128] = {};
static bool g_帧时间改变 = false;
float64 S_物体::g_前一帧 = 0.0;
float64 S_物体::g_当前帧 = 0.0;

bool                     S_物体::g_更新曲线关键帧 = true;
S_物体*                  S_物体::g_包围盒物体 = nullptr;
S_板载缓存*              S_物体::g_变换矩阵 = nullptr;
S_板载缓存*              S_物体::g_物体属性 = nullptr;
std::vector<S_板载缓存*> S_物体::g_物体颜色;

S_板载缓存* S_物体::g_骨骼长度 = nullptr;
S_板载缓存* S_物体::g_姿态变换 = nullptr;
S_板载缓存* S_物体::g_骨骼变换 = nullptr;




void S_物体变换::f_set矩阵(const float32* mat) {
	m_矩阵 = *((const Mat44f*)mat);
}





S_物体::S_物体(E_物体类型 type, uint32 id_name) : m_Type(type), S_Object(id_name), m_UpdateGPU参数布局(true){
	m_UserData = nullptr;
	m_Data = nullptr;
	m_DataNum = 0;

	m_实例ID = 0;
	//m_实例数量 = 1;
	m_变换ID = 0;
	m_TimeOffset = 0.0f;
	f_TranformInit(m_变换);

	m_变换矩阵 = {};
	m_物体属性 = {};
	m_光追实例加速结构 = {};

	m_父物体		= nullptr;
	//m_物理体		= nullptr;
	m_独立缩放 = nullptr;
	//m_实例颜色 = {};
	
	m_骨架			= nullptr;
	m_位置 = nullptr;
	m_旋转 = nullptr;
	m_缩放 = nullptr;
	//m_间接 = nullptr;
	//f_df_init_GPU参数布局(&m_GPU参数布局);

	switch (type)
	{
		case E_物体类型::t_实例:
			m_是否实例 = true;
			break;
		default:
			m_是否实例 = false;
			break;
	}
	//m_显示 = true;
	m_根实例	= false;
	
	m_可拾取	= true;
	m_渲染		= true;
	m_销毁      = false;
	
	m_isUpdateMatrix = true;
	m_isUpdate = true;
	
	m_PickIndirect = {};
}

S_物体::~S_物体() {
	if (m_变换矩阵.m_Buf) f_buf_erase(m_变换矩阵);
	if (m_物体属性.m_Buf) f_buf_erase(m_物体属性);
	for (auto& e : m_实例颜色) {
		if (e.m_Buf) f_buf_erase(e);
	}
	
	//g_物体容器.f_remove(m_ID);
	free(m_Data);
	m_Data = 0;
	m_DataNum = 0;

}


void S_物体::f_set位置(float32 x, float32 y, float32 z) {
	m_变换.location.x = x;
	m_变换.location.y = y;
	m_变换.location.z = z;

	m_isUpdate = true;
}
void S_物体::f_set旋转(float32 x, float32 y, float32 z) {
	m_变换.rotation.x = x;
	m_变换.rotation.y = y;
	m_变换.rotation.z = z;

	m_isUpdate = true;
}
void S_物体::f_set缩放(float32 x, float32 y, float32 z) {
	m_变换.scale.x = x;
	m_变换.scale.y = y;
	m_变换.scale.z = z;

	m_isUpdate = true;
}

void S_物体::f_set位置(const vec3& xyz, uint32 实例) {
	m_变换.location = xyz;
	//if (m_是否实例) {
	//	m_父物体->f_set位置(xyz, 实例);
	//}
	m_isUpdate = true;
}

void S_物体::f_set旋转(const vec3& xyz, uint32 实例) {
	m_变换.rotation = xyz;
	m_isUpdate = true;
}

void S_物体::f_set缩放(const vec3& xyz, uint32 实例) {
	m_变换.scale = xyz;
	m_isUpdate = true;
}



vec3 S_物体::f_get位置() { 
	if (m_位置 && g_更新曲线关键帧) {
		float64 t = g_当前帧 + m_TimeOffset;
		m_变换.location = f_an_曲线值(m_位置, t);
	}
	return m_变换.location; 
}

vec3 S_物体::f_get旋转() { 
	if (m_旋转 && g_更新曲线关键帧) {
		float64 t = g_当前帧 + m_TimeOffset;
		m_变换.rotation = f_an_曲线值(m_旋转, t);
	}
	return m_变换.rotation; 
}

vec3 S_物体::f_get缩放() { 
	if (m_缩放 && g_更新曲线关键帧) {
		float64 t = g_当前帧 + m_TimeOffset;
		m_变换.scale = f_an_曲线值(m_缩放, t);
	}
	return m_变换.scale; 
}



vec4 S_物体::f_get四元数() {
	return f_graph_欧拉角转四元数(m_变换.rotation);
}

std::vector<Mat44f> S_物体::f_get矩阵2(uint32 ID) {
	if (m_变换矩阵.m_Mem.m_大小) {
		std::vector<Mat44f> mat(m_变换矩阵.m_Mem.m_大小);
		for (uint32 i = 0; i < m_变换矩阵.m_Mem.m_大小; ++i) {
			mat[i] = f_buf_Mat44_at(m_变换矩阵, i);
		}

		/*m_变换矩阵->f_map();
		for (uint32 i = 0; i < m_变换矩阵->m_Size; ++i) {
			mat[i] = *((Mat44f*)(m_变换矩阵->m_mappedPtr));
		}
		m_变换矩阵->f_unmap();*/

		return mat;
	}
	return {};
}

C_Mat44 S_物体::f_get矩阵() const {
	C_Mat44 mat = C_Mat44::kIdentity;
	*((Mat44f*)mat.columns) = f_mat44_构建XYZ变换矩阵(m_变换);
	return mat;
}

Mat44f S_物体::f_get矩阵2() const {
	Mat44f m = f_mat44_构建XYZ变换矩阵(m_变换);
	return m;
}


void S_物体::f_set矩阵(const Mat44f* mat) {
	f_buf_Mat44_at(m_父物体->m_变换矩阵, m_变换ID) = *mat;
}

void S_物体::f_set矩阵(const Mat44f* mat, uint32 id) {
	f_buf_Mat44_at(m_父物体->m_变换矩阵, id) = *mat;
}



void S_物体::f_setData(void* data, uint16 loc) {
	assert(loc < m_DataNum);
	m_Data[loc] = data;
	m_isUpdate = true;
}

void S_物体::f_setDataNum(uint16 num) {
	if (num) {
		void** temp = m_Data;
		uint16 当前数据大小 = DEF_Min(num, m_DataNum);

		m_Data = (void**)calloc(num, sizeof(void*));
		for (uint16 i = 0; i < 当前数据大小; ++i) {
			m_Data[i] = temp[i];
		}

		for (uint16 i = 当前数据大小; i < num; ++i) {
			m_Data[i] = nullptr;
		}

	}
	else {
		if (m_Data) free(m_Data);
		m_Data = nullptr;
	}
	
	m_DataNum = num;
}



std::vector<S_物体*> S_物体::f_创建实例(uint32 num) {
	uint32 offset = m_变换矩阵.m_Mem.m_大小;
	f_buf_gresize(m_变换矩阵, offset + num);
	f_buf_gresize(m_物体属性, offset + num);

	for (auto& e : m_实例颜色) {
		f_buf_gresize(e, offset + num);
	}

	std::vector<S_物体*> objs(num);
	for (uint16 i = 0; i < num; ++i) {
		objs[i] = new S_物体(m_Type, 0);
		objs[i]->m_实例ID = offset + i;
		objs[i]->m_是否实例 = true;
	}
	
	return objs;
}


static Inline void f_物体变换生成(S_物体* ob, Mat44f* 矩阵, const Mat44f* 父级变换) {
	float64 t = ob->g_当前帧 + ob->m_TimeOffset;

	vec3 loc = ob->m_变换.location;
	vec3 rot = ob->m_变换.rotation;
	vec3 scale = ob->m_变换.scale;
	

	if (S_物体::g_更新曲线关键帧) {
		/*if (ob->m_位置) {
			loc = f_an_曲线值(ob->m_位置, t);
		}
		if (ob->m_旋转) {
			rot = f_an_曲线值(ob->m_旋转, t);
		}
		if (ob->m_缩放) {
			scale = f_an_曲线值(ob->m_缩放, t);
		}*/
		if (ob->m_位置) {
			ob->m_变换.location = f_an_曲线值(ob->m_位置, t);
		}
		if (ob->m_旋转) {
			ob->m_变换.rotation = f_an_曲线值(ob->m_旋转, t);
		}
		if (ob->m_缩放) {
			ob->m_变换.scale = f_an_曲线值(ob->m_缩放, t);
		}
	}

	Mat44f mat = f_mat44_构建XYZ变换矩阵({ loc, rot, scale });

	if (父级变换) {
		mat = (*父级变换) * mat;
	}
	(*矩阵) = mat;
}

static Inline void f_骨骼物体变换生成(S_物体* ob, Mat44f* 矩阵, const Mat44f* 父级变换) {
	
	float64 t = ob->g_当前帧 + ob->m_TimeOffset;

	vec3 loc = ob->m_变换.location;
	if (ob->m_位置) {
		loc = f_an_曲线值(ob->m_位置, t);
	}

	vec3 rot = ob->m_变换.rotation;
	if (ob->m_旋转) {
		rot = f_an_曲线值(ob->m_旋转, t);
	}

	vec3 scale = ob->m_变换.scale;
	if (ob->m_缩放) {
		scale = f_an_曲线值(ob->m_缩放, t);
	}
	Mat44f mat = f_mat44_构建XYZ变换矩阵({ loc, rot , scale});

	if (父级变换) {
		mat = (*父级变换) * mat;
	}
	(*矩阵) = mat;



	if (!ob->m_骨架) return;

	auto mat_ptr = f_buf_Mat44_ptr(ob->m_骨架->m_变换姿态);

	loc = DEF_骨骼朝向;
	loc *= f_buf_F32_at(ob->m_骨架->m_骨骼长度, ob->m_实例ID);

	mat = f_mat44_构建XYZ变换矩阵({ loc, rot, {1,1,1}});
	if (父级变换) {
		mat = (*父级变换) * mat;
	}
	mat_ptr[ob->m_实例ID] = mat;

	mat_ptr[ob->m_实例ID + ob->m_骨架->m_骨头数量].m00 = scale.x;
	mat_ptr[ob->m_实例ID + ob->m_骨架->m_骨头数量].m01 = scale.y;
	mat_ptr[ob->m_实例ID + ob->m_骨架->m_骨头数量].m02 = scale.z;

	return;





	vec3 骨骼端点 = mat * vec3{ 0, 0, 0 };
	vec3 骨骼端点E = mat * vec3{ 0, 0, 1 };
	//起点 = (*父级变换) * 起点;
	vec3 原_骨骼方向 = vec_normalize2(骨骼端点E - 骨骼端点);
	

	Mat44f mat后半段变换矩阵重新赋值 = f_mat44_identity();
	mat后半段变换矩阵重新赋值.m00 = scale.x;
	mat后半段变换矩阵重新赋值.m01 = scale.y;
	mat后半段变换矩阵重新赋值.m02 = scale.z;


	
	//auto mat_ptr = f_buf_map板载缓存<Mat44f>(ob->m_骨架->m_姿态变换);
	//引用蒙皮传入GPU中的变换
	if (ob->m_位置) {
		loc = f_an_曲线值(ob->m_位置, 0);
	}
	rot = ob->m_变换.rotation;
	if (ob->m_旋转) {
		rot = f_an_曲线值(ob->m_旋转, 0);
	}
	scale = ob->m_变换.scale;
	if (ob->m_缩放) {
		scale = f_an_曲线值(ob->m_缩放, 0);
	}
	mat = f_mat44_构建XYZ变换矩阵({ loc, rot , scale });
	


	vec3 初始端点 = {};
	vec3 骨骼端点B = {};
	
	if (ob->m_父物体 && ob->m_父物体->m_Type == E_物体类型::t_骨骼) {
		auto 父变换 = mat_ptr[ob->m_父物体->m_实例ID];
		mat = 父变换 * mat;
		
		auto mat_s = mat_ptr[ob->m_父物体->m_实例ID + ob->m_骨架->m_骨头数量];
		scale.x = mat_s.m00;
		scale.y = mat_s.m01;
		scale.z = mat_s.m02;
		//父Q.w = q.m13;
	}
	else {
		if (父级变换) mat = (*父级变换) * mat;
	}
	mat_ptr[ob->m_实例ID] = mat;
	初始端点  = mat * vec3{ 0, 0, 0 };
	骨骼端点B  = mat * vec3{ 0, 0, 1 };
	vec3 现姿态_骨骼方向 = vec_normalize2(骨骼端点B - 初始端点);
	

	float32 弧度AB = f_graph_两向量夹角弧度180(原_骨骼方向, 现姿态_骨骼方向);
	vec3 normal = vec_normalize2(vec_cross(原_骨骼方向, 现姿态_骨骼方向));
	auto quat = QuatFromAxisAngle({ normal.x, normal.y, normal.z }, 弧度AB);
	if (vec_len(normal) < 0.0000001) {
		quat = { 0,0,0,1 };
	}
	mat后半段变换矩阵重新赋值.m00 *= scale.x;
	mat后半段变换矩阵重新赋值.m01 *= scale.y;
	mat后半段变换矩阵重新赋值.m02 *= scale.z;


	mat后半段变换矩阵重新赋值.m10 = quat.x;
	mat后半段变换矩阵重新赋值.m11 = quat.y;
	mat后半段变换矩阵重新赋值.m12 = quat.z;
	mat后半段变换矩阵重新赋值.m13 = quat.w;
	
	mat后半段变换矩阵重新赋值.m20 = 骨骼端点.x;
	mat后半段变换矩阵重新赋值.m21 = 骨骼端点.y;
	mat后半段变换矩阵重新赋值.m22 = 骨骼端点.z;

	mat后半段变换矩阵重新赋值.m30 = 初始端点.x;
	mat后半段变换矩阵重新赋值.m31 = 初始端点.y;
	mat后半段变换矩阵重新赋值.m32 = 初始端点.z;
	mat_ptr[ob->m_实例ID + ob->m_骨架->m_骨头数量] = (mat后半段变换矩阵重新赋值);

}





void S_物体::f_Update(Mat44f* c, Mat44f* 父级变换) {
	//if (m_是否实例 == false) return;
	uint32 num = m_子物体.size();
	auto* objs = m_子物体.data();

	Mat44f* 当前矩阵ptr = c;
	if (m_变换矩阵.m_Buf && m_变换矩阵.m_Mem.m_大小) {
		//当前矩阵ptr = f_buf_map板载缓存<Mat44f>(m_变换矩阵);
		当前矩阵ptr = f_buf_Mat44_ptr(m_变换矩阵);
	}

	if (g_帧时间改变) {
		float64 t = g_当前帧 + m_TimeOffset;
		if (m_位置 || m_旋转 || m_缩放) {
			m_isUpdate = true;
		}
	}
	
	Mat44f mat = f_mat44_identity();
	if (父级变换) {
		mat = *父级变换;
	}

	if (this->m_父物体) {
		m_isUpdate |= this->m_父物体->m_isUpdate;
	}

	switch (m_Type)
	{
	case E_物体类型::t_摄像机:
	case E_物体类型::t_GL立即模式:
		return;
	case E_物体类型::t_实例:
	case E_物体类型::t_物体包:
	case E_物体类型::t_线:
	case E_物体类型::t_多边形:
	case E_物体类型::t_线段:
	case E_物体类型::t_网格: {
		//if (!m_是否实例) {
		//	if (m_UpdateGPU参数布局 && m_DataNum) {
		//		m_UpdateGPU参数布局 = false;
		//	}
		//}
		if (m_isUpdate || (m_位置 || m_旋转 || m_缩放)) {
			f_物体变换生成(this, &当前矩阵ptr[m_实例ID], &mat);
			m_isUpdateMatrix = true;
		}

		if (m_isUpdateMatrix) {
			if (m_DataNum) {
				S_Mesh* mesh = (S_Mesh*)(m_Data[0]);
				//S_Bounding bound;
				vec3 size = (mesh->m_Bound.max - mesh->m_Bound.min);

				mesh->m_包围盒.size = f_mat44_to_33(当前矩阵ptr[m_实例ID]) * size;
				
				vec3 最小 = 当前矩阵ptr[m_实例ID] * mesh->m_Bound.min;
				vec3 最大 = 当前矩阵ptr[m_实例ID] * mesh->m_Bound.max;
				mesh->m_包围盒.pos = 最小;
				mesh->m_包围盒.size = (最大 - 最小);
				mesh->m_包围盒.pos += mesh->m_包围盒.size * 0.5;
				
				m_包围盒 = mesh->m_包围盒;
			}
		}
		
		if (m_根实例) {
			//mat = f_mat44_构建XYZ变换矩阵(m_父物体->m_变换);
			//父级变换 = &当前矩阵ptr[m_实例ID];
		}
		else {
			父级变换 = &当前矩阵ptr[m_实例ID];
		}
		break;
	}

	case E_物体类型::t_虚拟体: {
		if (当前矩阵ptr) {
			if (m_isUpdate || (m_位置 || m_旋转 || m_缩放)) {
				f_物体变换生成(this, &当前矩阵ptr[m_实例ID], &mat);

				if (m_DataNum) {
					vec3 minBound = {}, maxBound = {};
					for (uint32 i = 0; i < m_DataNum; ++i) {
						S_Mesh* mesh = (S_Mesh*)(m_Data[i]);
						minBound = vec_Min(mesh->m_Bound.min, minBound);
						maxBound = vec_Min(mesh->m_Bound.max, maxBound);
					}
				
					
					vec3 size = (maxBound - minBound);
					m_包围盒.size = f_mat44_to_33(当前矩阵ptr[m_实例ID]) * size;
					m_包围盒.pos = 当前矩阵ptr[m_实例ID] * minBound;
					m_包围盒.pos += m_包围盒.size * 0.5;

					//mesh->m_包围盒.size = f_mat44_to_33(当前矩阵ptr[m_实例ID]) * size;
					//vec3 最小 = 当前矩阵ptr[m_实例ID] * mesh->m_Bound.min;
					//vec3 最大 = 当前矩阵ptr[m_实例ID] * mesh->m_Bound.max;
					//mesh->m_包围盒.pos = 最小;
					//mesh->m_包围盒.size = (最大 - 最小);
					//mesh->m_包围盒.pos += mesh->m_包围盒.size * 0.5;
					//m_包围盒 = mesh->m_包围盒;

				}
			}
			父级变换 = &当前矩阵ptr[m_实例ID];
		}
		break;
	}
		
	case E_物体类型::t_区域光_方形:
	case E_物体类型::t_区域光_圆形:
	case E_物体类型::t_聚光灯:
	case E_物体类型::t_区域光:
	case E_物体类型::t_平行光:
	case E_物体类型::t_点光源: {
		if (m_isUpdate || (m_位置 || m_旋转 || m_缩放)) {
			f_物体变换生成(this, &当前矩阵ptr[m_实例ID], &mat);
		}
		m_包围盒.pos = 当前矩阵ptr[m_实例ID] * vec3{0,0,0};
		m_包围盒.size = f_mat44_to_33(当前矩阵ptr[m_实例ID]) * m_变换.scale;
		父级变换 = &当前矩阵ptr[m_实例ID];

		//for (uint32 j = 0; j < m_DataNum; ++j) {
		//	S_Mesh* mesh = (S_Mesh*)(m_Data[j]);
		//	if (mesh->m_间接) {
		//		auto indirect_ptr = f_buf_Indirect_ptr(*mesh->m_间接);
		//		for (uint32 i = 0; i < mesh->m_间接->m_Mem.m_大小; ++i) {
		//			indirect_ptr[i].firstInstance = m_变换矩阵.m_Mem.m_偏移 + i;
		//		}
		//	}
		//}
		break;
	}
		

	case E_物体类型::t_灯光:
	case E_物体类型::t_包: {
		for (uint32 j=0; j < m_DataNum; ++j) {
			S_Mesh* mesh = (S_Mesh*)(m_Data[j]);
			if (mesh->m_间接 && mesh->m_间接->m_Mem.m_大小) {
				auto indirect_ptr = f_buf_Indirect_ptr(*mesh->m_间接);
				for (uint32 i = 0; i < mesh->m_间接->m_Mem.m_大小; ++i) {
					//indirect_ptr[i].firstInstance = m_变换矩阵.m_Mem.m_偏移 + i;
					indirect_ptr[i].firstInstance = i;
					//indirect_ptr[i].firstInstance = 0;
				}
			}
		}
		//父级变换 = &当前矩阵ptr[m_实例ID];
		break;
	}
	case E_物体类型::t_骨架:
		if (m_isUpdate) {
			f_物体变换生成(this, &当前矩阵ptr[m_实例ID], &mat);
		}
		父级变换 = &当前矩阵ptr[m_实例ID];
		break;

	case E_物体类型::t_骨骼: {
		if (当前矩阵ptr) {
			if (m_isUpdate) {
				f_骨骼物体变换生成(this, &当前矩阵ptr[m_实例ID], &mat);
			}
			父级变换 = &当前矩阵ptr[m_实例ID];
		}
		
		break;
	}
	default:
		break;
	}

	

	for (uint32 i = 0; i < num; ++i) objs[i]->f_Update(当前矩阵ptr, 父级变换);


	switch (m_Type) {
	case E_物体类型::t_骨架: {
		auto* 骨架 = f_ob_from骨架(this);
		if (骨架) {
			if (m_isUpdate) {
				f_buf_copy(骨架->m_骨骼变换, 骨架->m_变换姿态);
			}

			if (骨架->m_IK数量) {
				f_ob_更新骨骼IK(this, 骨架, 当前矩阵ptr, mat);
			}
			if (骨架->m_骨头数量) {
				f_ob_构建骨骼变换GPU数据(骨架, 当前矩阵ptr);
			}
		}
		break;
	}
	default:
		break;
	}



	m_isUpdate = false;
	m_isUpdateMatrix = false;
}


void S_物体::f_绘制(S_渲染参数& 参数) {
	if (m_DataNum && m_渲染) {

		S_渲染参数 渲染参数 = 参数;
		//渲染参数.m_矩阵 = m_变换矩阵;
		//渲染参数.m_线宽 = m_线宽;
		switch (m_Type) {
		case E_物体类型::t_GL立即模式:
		case E_物体类型::t_实例:
		case E_物体类型::t_摄像机:
		case E_物体类型::t_骨骼:
		case E_物体类型::t_骨架:
		case E_物体类型::t_点光源:
		case E_物体类型::t_聚光灯:
		case E_物体类型::t_区域光:
		case E_物体类型::t_平行光:
		//case E_物体类型::t_虚拟体:
			break;
		default:
			for (uint8 i = 0; i < m_DataNum; ++i) {
				S_Mesh* mesh = ((S_Mesh*)(m_Data[i]));
				if (!(mesh->m_显示) || m_是否实例 || !mesh->m_GPU参数布局.m_参数数量) continue;

				mesh->m_Material->mf_GPU参数配置(mesh->m_Material, this, mesh, i);
				

				mesh->m_GPU参数布局.m_参数槽[0] = 参数.m_视图投影矩阵;
				mesh->m_GPU参数布局.m_绑定位置[0] = 0;
				mesh->m_GPU参数布局.m_参数槽[1] = g_变换矩阵;
				mesh->m_GPU参数布局.m_绑定位置[1] = 1;

				f_setGPU参数布局(mesh->m_Material, mesh->m_GPU参数布局);


				渲染参数.m_GPU参数 = mesh->m_Material->m_GPU参数set;
				渲染参数.m_实例数量 = m_变换矩阵.m_Mem.m_大小;
				//渲染参数.m_实例偏移 = m_变换矩阵.m_Mem.m_偏移;
				渲染参数.m_实例偏移 = 0;
				渲染参数.m_线宽 = mesh->m_线宽;
				
				if (mesh->m_绘制属性) {
					mesh->m_绘制属性->MatrixOffset = m_变换矩阵.m_Mem.m_偏移;
					mesh->m_绘制属性->ColorPropOffset = m_实例颜色[i].m_Mem.m_偏移;
				}

				if (mesh->m_间接 && mesh->m_间接->m_Mem.m_大小) {
					//f_buf_Indirect_ptr(*mesh->m_间接)->firstInstance = m_变换矩阵.m_Mem.m_偏移;
					f_buf_Indirect_ptr(*mesh->m_间接)->firstInstance = 0;
				}
				
				mesh->f_绘制(渲染参数);

			}
			break;
		}
	}

	//return;
	uint32 num = m_子物体.size();
	auto* objs = m_子物体.data();
	for (uint32 i = 0; i < num; ++i) if(objs[i]->m_是否实例 == false) objs[i]->f_绘制(参数);

}

void S_物体::f_打开可视通道(uint8 通道) {
	if (m_是否实例 && m_父物体) {
		m_父物体->f_打开可视通道(通道);
	}
	else {
		switch (m_Type) {
		case E_物体类型::t_多边形:
		case E_物体类型::t_网格: {
			((S_Mesh*)(m_Data[通道]))->m_显示 = true;
			break;
		}
		}
	}
	
}

void S_物体::f_关闭可视通道(uint8 通道) {
	if (m_是否实例 && m_父物体) {
		m_父物体->f_关闭可视通道(通道);
	}
	else {
		switch (m_Type) {
		case E_物体类型::t_多边形:
		case E_物体类型::t_网格: {
			((S_Mesh*)(m_Data[通道]))->m_显示 = false;
			break;
		}
		}
	}
	
}

void S_物体::f_构建底层加速结构() {

}





S_物体* f_get物体(uint32 id_name) {
	if (g_物体容器.f_Key存在(id_name)) {
		return g_物体容器[id_name];
	}
	return nullptr;
}

S_Mesh* f_ob_fromMesh(const S_物体* froObj, uint32 loc) {
	if (froObj->m_是否实例) {
		return f_ob_fromMesh(froObj->m_父物体);
	}

	switch (froObj->m_Type) {
	//case E_物体类型::t_骨架:
		case E_物体类型::t_线:
		case E_物体类型::t_包:
		case E_物体类型::t_虚拟体:
		case E_物体类型::t_灯光:
		case E_物体类型::t_线段:
		case E_物体类型::t_多边形:
		case E_物体类型::t_网格: {
			if (froObj->m_Data) {
				return (S_Mesh*)(froObj->m_Data[loc]);
			}
			break;
		}
		default:
			break;
	}

	return nullptr;
}


void f_Ob_打开可视通道(uint8 通道) {
	g_可视[通道] = true;
}
void f_Ob_关闭可视通道(uint8 通道) {
	g_可视[通道] = false;
}



void f_ob_创建矩阵(S_物体* ob, S_设备环境& ctx, uint32 num) {
	ob->m_变换矩阵 = f_buf_alloc(S_物体::g_变换矩阵, num);
	ob->m_物体属性 = f_buf_alloc(S_物体::g_物体属性, num);
	
	for (uint32 i = 0; i < ob->m_DataNum; ++i) {
		ob->m_实例颜色[i] = f_buf_alloc(S_物体::g_物体颜色[i], num);
	}

	ob->m_UpdateGPU参数布局 = true;
	ob->m_变换ID            = ob->m_变换矩阵.m_Mem.m_偏移;

	f_buf_Mat44_at(ob->m_变换矩阵, ob->m_实例ID) = f_mat44_identity();
	f_buf_物体变换属性_at(ob->m_物体属性, ob->m_实例ID) = MeshProp_Init();

}

void f_ob_添加矩阵(S_物体* ob, uint32 loc) {
	if (loc == -1) {
		loc = ob->m_变换矩阵.m_Mem.m_大小;
	}
	
	auto mat = f_mat44_identity();
	auto prop = MeshProp_Init();
	f_buf_push_back(ob->m_变换矩阵, (uint8*)&mat, 1);
	f_buf_push_back(ob->m_物体属性, (uint8*)&prop, 1);

	uint32 color = f_PackData4X8({128, 128, 128, 255});
	for (uint32 i = 0; i < ob->m_DataNum; ++i) {
		f_buf_push_back(ob->m_实例颜色[i], (uint8*)&color, 1);
		//ob->m_实例颜色[i] = f_buf_alloc(S_物体::g_物体颜色[i], ob->m_变换矩阵.m_Mem.m_大小);
	}
	//for (auto& e : ob->m_实例颜色) {
	//	if (e.m_Buf) {
	//		f_buf_push_back(e, (uint8*)&color, 1);
	//	}
	//	else {
	//		e = f_buf_alloc(S_物体::g_物体颜色[loc], ob->m_变换矩阵.m_Mem.m_大小);
	//		f_buf_UI32_at(e, loc) = color;
	//	}
	//}

	ob->m_变换ID = ob->m_变换矩阵.m_Mem.m_偏移;
}

void f_ob_删除矩阵(S_物体* ob, uint32 loc, uint32 num) {
	f_buf_erase(ob->m_变换矩阵, loc, num);
	f_buf_erase(ob->m_物体属性, loc, num);
}

void f_ob_清除矩阵(S_物体* ob, uint32 num) {
	f_buf_erase(ob->m_变换矩阵, 0, num);
	for (uint32 i = 0; i < ob->m_DataNum; ++i) {
		f_buf_erase(ob->m_实例颜色[i], 0, num);
	}
}

S_物体* f_ob_创建网格物体(S_设备环境 ctx) {
	S_物体* ob = new S_物体(E_物体类型::t_网格);
	f_ob_创建矩阵(ob, ctx);
	return ob;
}

S_骨骼* f_ob_get骨骼数据(S_物体* ob, uint8 loc) {
	switch (ob->m_Type) {
		case E_物体类型::t_骨骼:
			return (S_骨骼*)(ob->m_Data[loc]);
	}
	return nullptr;
}

Mat44f f_ob_get实例变换矩阵(S_物体* Obj, uint32 ID) {
	if (ID < Obj->m_变换矩阵.m_Mem.m_大小) {
		return f_buf_Mat44_at(Obj->m_变换矩阵, ID);
		//Mat44f* 当前矩阵prt = f_buf_map板载缓存<Mat44f>(Obj->m_变换矩阵);
		//Mat44f mat = 当前矩阵prt[ID];
		//f_buf_unmap板载缓存(Obj->m_变换矩阵);
		//return mat;
	}
	else {
		if (Obj->m_父物体) {
			return f_ob_get实例变换矩阵(Obj->m_父物体, ID);
		}
	}
	return f_mat44_identity();
}

//Mat44f f_ob_get父对象变换矩阵(S_物体* Obj, uint32 ID, uint32 depth, bool 包含顶层) {
//	if (Obj->m_父物体) {
//		++depth;
//
//		switch (Obj->m_父物体->m_Type) {
//		case E_物体类型::t_骨骼:
//		
//		case E_物体类型::t_虚拟体:
//		case E_物体类型::t_点光源:
//		case E_物体类型::t_聚光灯:
//		case E_物体类型::t_区域光_圆形:
//		case E_物体类型::t_区域光_方形:
//		case E_物体类型::t_实例:
//			return f_ob_get父对象变换矩阵(Obj->m_父物体, ID, depth);
//
//		//case E_物体数据::t_物体包:
//		case E_物体类型::t_骨架:
//			if (!ID) return f_ob_get父对象变换矩阵(Obj->m_父物体, ID, depth);
//			return f_ob_get实例变换矩阵(Obj->m_父物体, ID);
//			break;
//		default:
//			break;
//		}
//
//
//		if (Obj->m_父物体->m_变换矩阵.m_Mem.m_大小) {
//			return f_ob_get父对象变换矩阵(Obj->m_父物体, ID, depth);
//		}
//
//
//		return f_ob_get实例变换矩阵(Obj->m_父物体, ID);
//	}
//
//	if (depth || 包含顶层) {
//		return f_ob_get实例变换矩阵(Obj, Obj->m_实例ID);
//	}
//
//	return f_mat44_identity();
//}

Mat44f f_ob_get父对象变换矩阵(S_物体* Obj, uint32 depth, bool 包含顶层) {
	if (Obj->m_父物体) {
		++depth;
 
		switch (Obj->m_Type) {
		case E_物体类型::t_骨架:
		case E_物体类型::t_骨骼:
		case E_物体类型::t_虚拟体:
		case E_物体类型::t_点光源:
		case E_物体类型::t_聚光灯:
		//case E_物体类型::t_区域光_圆形:
		//case E_物体类型::t_区域光_方形:
		//case E_物体类型::t_实例:
			return f_ob_get父对象变换矩阵(Obj->m_父物体, depth);
		default:
			break;
		}

		if (!Obj->m_父物体->m_变换矩阵.m_Mem.m_大小) {
			return f_ob_get父对象变换矩阵(Obj->m_父物体, depth);
		}


		return f_ob_get实例变换矩阵(Obj->m_父物体, Obj->m_实例ID);
	}

	if (包含顶层) {
		return f_ob_get实例变换矩阵(Obj, Obj->m_实例ID);
	}

	return f_mat44_identity();
}










void f_ob_步进时间帧(float32 f) {
	S_物体::g_前一帧 = S_物体::g_当前帧;
	S_物体::g_当前帧 += f;

	g_帧时间改变 = true;
}

void f_ob_set步进时间帧(float64 f) {
	S_物体::g_前一帧 = S_物体::g_当前帧;
	S_物体::g_当前帧 = f;

	g_帧时间改变 = true;
}

Mat44f f_ob_构建XYZ变换矩阵euler(const S_物体* ob) {
	C_Mat44 mat = C_Mat44::kIdentity;
	Mat44f m = f_mat44_identity();

	auto rx = f_构建旋转矩阵(ob->m_变换.rotation.x, { 1.0f,0.0f,0.0f });
	auto ry = f_构建旋转矩阵(ob->m_变换.rotation.y, { 0.0f,1.0f,0.0f });
	auto rz = f_构建旋转矩阵(ob->m_变换.rotation.z, { 0.0f,0.0f,1.0f });
	auto s = f_mat4_构建缩放矩阵(ob->m_变换.scale);

	//mat *= f_构建移动矩阵(ob->m_变换.location);

	//mat *= rx * ry * rz;
	mat *= rx;
	mat *= ry;
	mat *= rz;

	m = *((Mat44f*)&mat);
	//m *= s;
	return m;
}

Mat44f f_ob_构建XYZ变换矩阵euler(const vec3& rot) {
	C_Mat44 mat = C_Mat44::kIdentity;
	Mat44f m = f_mat44_identity();

	auto rx = f_构建旋转矩阵(rot.x, { 1.0f,0.0f,0.0f });
	auto ry = f_构建旋转矩阵(rot.y, { 0.0f,1.0f,0.0f });
	auto rz = f_构建旋转矩阵(rot.z, { 0.0f,0.0f,1.0f });

	mat *= rx;
	mat *= ry;
	mat *= rz;

	m = *((Mat44f*)&mat);
	return m;
}


S_骨骼IK* f_ob_创建IK() {
	S_骨骼IK* ik = (S_骨骼IK*)malloc(sizeof(S_骨骼IK));
	(*ik) = {};
	ik->m_迭代次数 = 1;
	return ik;
}

void f_ob_销毁IK(S_骨骼IK* ik) {
	free(ik);
}

S_骨骼IK** f_ob_添加IK(S_骨架* 骨骼, uint16 IK数量) {
	骨骼->m_IK = (S_骨骼IK**)calloc(IK数量, sizeof(S_骨骼IK*));
	骨骼->m_IK数量 = IK数量;
	return 骨骼->m_IK;
}

S_骨架* f_ob_创建骨架() {
	S_骨架* 骨骼 = (S_骨架*)malloc(sizeof(S_骨架));

	//骨骼->m_骨骼属性 = f_buf_alloc();
	骨骼->m_骨骼长度 = f_buf_alloc(S_物体::g_骨骼长度, 0);
	骨骼->m_初始姿态 = f_buf_alloc(S_物体::g_姿态变换, 0);
	骨骼->m_变换姿态 = f_buf_alloc(S_物体::g_姿态变换, 0);
	骨骼->m_骨骼变换 = f_buf_alloc(S_物体::g_骨骼变换, 0);


	骨骼->m_骨头数量 = 0;
	骨骼->m_IK数量 = 0;
	骨骼->m_IK = nullptr;

	return 骨骼;
}

S_骨架* f_ob_from骨架(const S_物体* froObj, uint32 loc) {
	assert(froObj->m_Data);
	switch (froObj->m_Type) {
		case E_物体类型::t_骨架:
			return (S_骨架*)(froObj->m_Data[loc]);
	}
	return nullptr;
}


static S_物体* f_ob_查找IK旋转向量中间骨骼(S_物体* 骨骼, S_骨骼IK* IK, uint32& depth) {
	if (骨骼->m_父物体) {
		++depth;
		if (骨骼->m_父物体 == IK->m_始端) {
			goto To_根骨骼;
		}
		else {
			S_物体* r_ob = f_ob_查找IK旋转向量中间骨骼(骨骼->m_父物体, IK, depth);
			if (r_ob) {
				return r_ob;
			}
		}
	}
	else {
	To_根骨骼:
		depth = 骨骼->m_实例ID;
		return 骨骼;
	}
	return nullptr;
}


static Mat44f f_ob_更新子骨骼IK(S_物体* 骨骼, S_骨骼IK* IK) {
	Mat44f 当前骨骼矩阵 = f_mat44_构建XYZ变换矩阵(骨骼->m_变换);

	if (骨骼->m_父物体) {
		if (骨骼->m_父物体 == IK->m_始端) {

		}
		else {
			Mat44f 父骨骼矩阵 = f_ob_更新子骨骼IK(骨骼->m_父物体, IK);

			当前骨骼矩阵 = 父骨骼矩阵 * 当前骨骼矩阵;
		}
	}

	当前骨骼矩阵;

	return 当前骨骼矩阵;
}

vec3 f_ob_计算骨骼IK中点(S_骨骼IK* IK) {
	vec3 vs = {};
	vec3 ve = {};
	if (IK->m_始端) vs = f_ob_计算骨骼IK点(IK->m_始端, false);
	if (IK->m_始端) ve = f_ob_计算骨骼IK点(IK->m_末端, true);

	return vs + (ve - vs) * 0.5f;

	if (IK->m_末端) {
		uint32 中点ID = 0;
		S_物体* ob = f_ob_查找IK旋转向量中间骨骼(IK->m_末端, IK, 中点ID);
		auto mat = f_ob_get父对象变换矩阵(IK->m_末端, 中点ID);

		S_骨骼* 骨骼 = f_ob_get骨骼数据(ob);
		return (mat * f_mat44_构建移动矩阵({ 0, 0, 骨骼->m_长度 })) * vec3 {};
		return mat * vec3 {};
	}
	return {};
}

vec3 f_ob_计算骨骼IK点(S_物体* ob, bool 尾部) {
	
	auto mat = f_ob_get父对象变换矩阵(ob, ob->m_实例ID);
	S_骨骼* 骨骼 = f_ob_get骨骼数据(ob);

	vec3 coord;
	if (尾部) {
		coord = (mat * f_mat44_构建移动矩阵({ 0, 0, 骨骼->m_长度 })) * vec3{};
	}
	else {
		coord = mat * vec3{};
	}
	return coord;
}

vec4 f_ob_计算IK旋转向量(S_骨骼IK* IK) {
	vec3 vs = {};
	vec3 ve = {};
	if (IK->m_始端) vs = f_ob_计算骨骼IK点(IK->m_始端, false);
	if (IK->m_末端) ve = f_ob_计算骨骼IK点(IK->m_末端, true);

	vec3 原末端控制向量 = (ve - vs);
	vec3 中点坐标 = vs + 原末端控制向量 * 0.5f;
	
	原末端控制向量 = vec_normalize(原末端控制向量);
	
	vec3 IK控制点到中点向量 = vec_normalize(IK->m_末端坐标 - 中点坐标);
	vec3 旋转向量 = vec_normalize(vec_cross(原末端控制向量, IK控制点到中点向量));
	return { 旋转向量.x, 旋转向量.y, 旋转向量.z , float32(-f_graph_两向量夹角弧度180(原末端控制向量, IK控制点到中点向量)) };
	return f_graph_从轴向角度计算四元数(旋转向量, f_graph_两向量夹角弧度180(原末端控制向量, IK控制点到中点向量));
}

vec4 f_ob_计算IK旋转向量(S_骨架* 骨架, S_骨骼IK* IK, vec3& 原控制向量, float32& 原控制点距离, float32& 新控制点距离) {
	auto mat_ptr = f_buf_Mat44_ptr(骨架->m_变换姿态);
	S_骨骼* 骨骼 = f_ob_get骨骼数据(IK->m_末端);

	vec3 vs = mat_ptr[IK->m_始端->m_实例ID] * vec3{};
	vec3 ve = mat_ptr[IK->m_末端->m_实例ID] * vec3{ 0, 0, 骨骼->m_长度 };


	//vec3 vs = f_ob_计算骨骼IK点(IK->m_始端, false);
	//vec3 ve = f_ob_计算骨骼IK点(IK->m_末端, true);
	原控制向量 = (ve - vs);
	vec3 中点坐标 = vs + 原控制向量 * 0.5f;

	原控制点距离 = vec_normalize(&原控制向量);

	vec3 IK控制点到中点向量 = IK->m_末端坐标 - 中点坐标;
	新控制点距离 = vec_normalize(&IK控制点到中点向量);
	vec3 旋转向量 = vec_normalize(vec_cross(原控制向量, IK控制点到中点向量));
	return { 旋转向量.x, 旋转向量.y, 旋转向量.z , float32(-f_graph_两向量夹角弧度180(原控制向量, IK控制点到中点向量)) };
}


void f_ob_更新骨骼IK(S_物体* ob, S_骨架* 骨架, Mat44f* 骨骼物体变换矩阵, const Mat44f& 父级变换) {
	if(!骨架->m_骨头数量 || !骨架->m_IK数量) return;

	float32* 骨骼长度 = f_buf_F32_ptr(骨架->m_骨骼长度);
	auto 姿态变换_ptr = f_buf_Mat44_ptr(骨架->m_骨骼变换);

	uint32 num = 骨架->m_骨骼变换.m_Mem.m_大小;
	auto mat = f_mat44_Inverse(父级变换);
	std::vector<vec3> 新控制点(num);
	for (auto& e : ob->m_子物体) {
		f_ob_ge骨节坐标(e, 新控制点.data(), 姿态变换_ptr, 骨骼长度, mat);
	}

	std::vector<Mat44f> tempMat(num);
	memcpy(tempMat.data(), 姿态变换_ptr, sizeof(Mat44f) * tempMat.size());

	for (uint32 i = 0; i < 骨架->m_IK数量; ++i) {
		S_骨骼IK* ik = 骨架->m_IK[i];
		
		if (ik && ik->m_始端 && ik->m_末端) {
			for (uint32 k = 0; k < 12; ++k) {
				f_ob_解算IK骨骼IK步进坐标(ik, 新控制点.data(), tempMat.data(), 骨骼长度, mat);

				for (auto& e : ob->m_子物体) {
					f_ob_从骨节更新编辑骨骼(e, 新控制点.data(), 骨骼长度, tempMat.data(), { 0,0,0,1 }, 父级变换, e->m_变换.location, 0);
				}
			}
			memcpy(骨骼物体变换矩阵, tempMat.data(), sizeof(Mat44f) * tempMat.size());
		}
	}
}

void f_ob_解算IK骨骼(S_骨骼IK* ik, Mat44f* 骨骼物体变换矩阵, const Mat44f* 骨骼变换矩阵, const float32* 骨骼长度, const Mat44f& 父级变换) {
	std::vector<S_物体*> 骨骼物体链;
	std::vector<float32> 骨骼偏移比例;

	S_物体* ob = ik->m_末端;
	vec3 末点坐标 = ik->m_末端坐标;
	std::vector<vec3> 修正旋转;
	std::vector<float32> 旋转角度;
	//Mat44f 父变换 = 骨骼物体变换矩阵[ik->m_始端->m_实例ID];
	for (;;) {
		骨骼物体链.push_back(ob);
		S_骨骼* 骨骼 = f_ob_get骨骼数据(ob);

		uint32 offset = ob->m_实例ID;
		Mat44f 变换 = 骨骼变换矩阵[offset];

		vec3 s = 变换 * vec3{ 0, 0, 0 };
		vec3 e = 变换 * vec3{ 0, 0, 骨骼长度[offset] };

		vec3 骨骼朝向 = e - s;
		vec3 新变更向量 = 末点坐标 - s;
		//vec3 新变更向量 = e - s;
		vec_normalize(&新变更向量);
		vec_normalize(&骨骼朝向);
		
		末点坐标 = 末点坐标 - 新变更向量 * 骨骼长度[offset];

		旋转角度.push_back(f_graph_两向量夹角弧度180(新变更向量, 骨骼朝向));
		//修正旋转.push_back(vec_cross(新变更向量, 骨骼朝向));
		修正旋转.push_back(新变更向量);

		
		if (!(ob->m_父物体) || ob == ik->m_始端) {
			break;
		}
		ob = ob->m_父物体;
	}


	float32 起始端骨骼长度;
	Mat44f 父变换;
	if (ik->m_始端->m_实例ID) {
		父变换 = 骨骼变换矩阵[ik->m_始端->m_父物体->m_实例ID];
		起始端骨骼长度 = 骨骼长度[ik->m_始端->m_父物体->m_实例ID];
	} else {
		父变换 = 父级变换;
		起始端骨骼长度 = 0;
	}

	uint32 num = 骨骼物体链.size();
	//auto rotMat = f_mat44_to_33(父变换);
	vec3 l = { 0,0, 起始端骨骼长度 };
	vec3 global_offset = (骨骼变换矩阵[ik->m_始端->m_实例ID] * f_mat44_构建移动矩阵(l) * vec3{ 0, 0, 0 });
	
	auto 偏移 = f_mat44_构建移动矩阵(global_offset);
	
	vec3 root骨骼反向 = 父变换 * vec3{0, 0, 0};
	root骨骼反向 = vec_normalize(骨骼变换矩阵[ik->m_始端->m_实例ID] * vec3{ 0, 0, 0 } - root骨骼反向);
	
	vec4 父骨骼旋转 = f_graph_quatNormalize(f_graph_quat两向量(root骨骼反向, DEF_骨骼朝向));
	for (int32 k = num; k > 0; ) {
		--k;
		uint32 offset = 骨骼物体链[k]->m_实例ID;

		auto 骨骼方向 = f_graph_quat变换坐标(f_graph_quat反向(父骨骼旋转), 修正旋转[k]);
		vec_normalize(&骨骼方向);

		auto 当前旋转四元数 = f_graph_quat两向量(骨骼方向, DEF_骨骼朝向);
		auto rot = f_graph_四元数转欧拉角(当前旋转四元数);

		auto 变换 = 骨骼物体链[k]->m_变换;
		变换.rotation = vec3{ -rot.x, -rot.y, rot.z };

		骨骼物体变换矩阵[offset] = 父变换 * f_mat44_构建XYZ变换矩阵(变换);
		父变换 = 骨骼物体变换矩阵[offset];

		父骨骼旋转 = f_graph_quatNormalize(f_graph_quat相乘(当前旋转四元数, 父骨骼旋转));
	}
}

void f_ob_解算IK骨骼IK步进坐标(S_骨骼IK* ik, vec3* 骨节, const Mat44f* 骨骼变换矩阵, const float32* 骨骼长度, const Mat44f& 父级变换) {
	auto mat = f_mat44_Inverse(父级变换);

	S_物体* ob = ik->m_末端;
	vec3 末点坐标 = ik->m_末端坐标;
	
	for (;;) {
		S_骨骼* 骨骼 = f_ob_get骨骼数据(ob);

		uint32 offset = ob->m_实例ID;
		
		vec3 s = 骨骼变换矩阵[offset] * vec3{ 0, 0, 0 };
		vec3 新变更向量 = (末点坐标 - s);
		vec_normalize(&新变更向量);
		
		骨节[offset] = 父级变换 * 末点坐标;

		末点坐标 = 末点坐标 - 新变更向量 * 骨骼长度[offset];

		if (!(ob->m_父物体) || ob == ik->m_始端) {
			break;
		}
		ob = ob->m_父物体;
	}
}


void f_ob_从骨节更新编辑骨骼(S_物体* 根骨骼
	, vec3* 骨节
	, const float32* 骨骼长度
	, Mat44f* 骨骼物体变换矩阵
	, const vec4& 父骨骼旋转
	, const Mat44f& 父矩阵
	, const vec3& s
	, float32 l) {

	uint32 num = 根骨骼->m_子物体.size();
	

	vec3 e = 骨节[根骨骼->m_实例ID];


	vec3 骨骼方向 = e - s;
	骨骼方向 = f_graph_quat变换坐标(f_graph_quat反向(父骨骼旋转), 骨骼方向);
	vec4 q = f_graph_quat两向量(骨骼方向, DEF_骨骼朝向);
	vec3 rot = f_graph_四元数转欧拉角(q);
	rot = vec3{ -rot.x, -rot.y, rot.z };


	S_Tranform tran = 根骨骼->m_变换;
	//f_TranformInit(tran);
	if (根骨骼->m_实例ID) {
		tran.location = { 0, 0, l };
	} else {
		tran.location = s;
	}
	
	tran.rotation = rot;
	骨骼物体变换矩阵[根骨骼->m_实例ID] = 父矩阵 * f_mat44_构建XYZ变换矩阵(tran);

	vec4 newQuat = f_graph_quatNormalize(f_graph_quat相乘(q, 父骨骼旋转));

	for (uint32 i = 0; i < num; ++i) {
		S_物体* 骨骼 = 根骨骼->m_子物体[i];
		S_骨骼* 骨骼数据 = f_ob_get骨骼数据(骨骼);

		f_ob_从骨节更新编辑骨骼(骨骼, 骨节, 骨骼长度, 骨骼物体变换矩阵, newQuat, 骨骼物体变换矩阵[根骨骼->m_实例ID], e, 骨骼长度[根骨骼->m_实例ID]);
	}
}

void f_ob_ge骨节坐标(S_物体* 根骨骼, vec3* 骨节, const Mat44f* 骨骼变换矩阵, const float32* 骨骼长度, const Mat44f& 父级变换) {
	uint32 num = 根骨骼->m_子物体.size();

	uint32 offset = 根骨骼->m_实例ID;
	骨节[offset] = 骨骼变换矩阵[offset] * vec3{ 0, 0, 骨骼长度[offset] };
	骨节[offset] = 父级变换 * 骨节[offset];

	for (uint32 i = 0; i < num; ++i) {
		S_物体* ob = 根骨骼->m_子物体[i];

		f_ob_ge骨节坐标(ob, 骨节, 骨骼变换矩阵, 骨骼长度, 父级变换);
	}
}


void f_ob_构建骨骼变换GPU数据(S_骨架* 骨架, const Mat44f* 骨骼变换矩阵) {
	
	auto mat_ptr = f_buf_Mat44_ptr(骨架->m_变换姿态);

#pragma omp parallel for num_threads(4)
	for (int32 i = 0; i < 骨架->m_骨头数量; ++i) {
		Mat44f mat后半段变换矩阵重新赋值 = f_mat44_identity();
		
		
		Mat44f mat = mat_ptr[i];
		vec3 骨骼端点S = mat * vec3{ 0, 0, 0 };
		vec3 骨骼端点E = mat * vec3{ 0, 0, 1 };
		vec3 原_骨骼方向 = vec_normalize2(骨骼端点E - 骨骼端点S);


		mat = 骨骼变换矩阵[i];
		vec3 骨骼端点A = mat * vec3{ 0, 0, 0 };
		vec3 骨骼端点B = mat * vec3{ 0, 0, 1 };
		vec3 现姿态_骨骼方向 = vec_normalize2(骨骼端点B - 骨骼端点A);


		auto quat = f_graph_quat两向量(原_骨骼方向, 现姿态_骨骼方向);
		if (vec_len(quat) < 0.0000001) {
			quat = { 0,0,0,1 };
		}


		//mat后半段变换矩阵重新赋值.m00 *= scale.x;
		//mat后半段变换矩阵重新赋值.m01 *= scale.y;
		//mat后半段变换矩阵重新赋值.m02 *= scale.z;

		mat后半段变换矩阵重新赋值.m10 = quat.x;
		mat后半段变换矩阵重新赋值.m11 = quat.y;
		mat后半段变换矩阵重新赋值.m12 = quat.z;
		mat后半段变换矩阵重新赋值.m13 = quat.w;

		mat后半段变换矩阵重新赋值.m20 = 骨骼端点S.x;
		mat后半段变换矩阵重新赋值.m21 = 骨骼端点S.y;
		mat后半段变换矩阵重新赋值.m22 = 骨骼端点S.z;

		mat后半段变换矩阵重新赋值.m30 = 骨骼端点A.x;
		mat后半段变换矩阵重新赋值.m31 = 骨骼端点A.y;
		mat后半段变换矩阵重新赋值.m32 = 骨骼端点A.z;

		mat_ptr[i + 骨架->m_骨头数量] = (mat后半段变换矩阵重新赋值);
	}
}





C_骨骼管理::C_骨骼管理() {

}

C_骨骼管理::~C_骨骼管理() {
	for (auto& e : m_骨骼容器) {
		free(e);
	}
}







void f_ob_构建光追实例加速结构(S_物体* ob, S_设备环境& ctx) {
	//auto* 绘图配置 = (S_绘图设备配置*)ctx.m_绘图设备配置;

	auto* mesh = f_ob_fromMesh(ob);
	if(!ob->m_光追实例加速结构.m_Buf) ob->m_光追实例加速结构 = f_buf_alloc(S_Mesh::g_实例AS, 0);


	uint32 实例数量 = DEF_Max(ob->m_子物体.size(), 1);
	f_buf_gresize(ob->m_光追实例加速结构, 实例数量);


	auto ptr_instance = f_buf_实例加速结构_ptr(ob->m_光追实例加速结构);
	auto* mat = f_buf_Mat44_ptr(ob->m_变换矩阵);

	for (uint32 i = 0; i < 实例数量; ++i) {
		auto matrix = f_mat3x4_转换(mat[i]);
		ptr_instance[i].transform = *((VkTransformMatrixKHR*)&matrix);
		ptr_instance[i].instanceCustomIndex = mesh->m_光追网格GPU地址引用.m_Mem.m_偏移;
		ptr_instance[i].mask = 0xff;
		ptr_instance[i].instanceShaderBindingTableRecordOffset = 0;
		ptr_instance[i].flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
		ptr_instance[i].accelerationStructureReference = f_buf_getAddress(*mesh->m_底层光追加速结构);
	}
}










/*std::vector<C_Mat44> S_物体::f_get矩阵(uint32 ID) {
	if (m_变换矩阵.m_Mem.m_大小) {
		std::vector<C_Mat44> mat(m_变换矩阵->m_Size);

		m_变换矩阵->f_map();
		for (uint32 i = 0; i < m_变换矩阵->m_Size; ++i) {
			*((Mat44f*)mat[i].columns) = *((Mat44f*)(m_变换矩阵->m_mappedPtr));
		}
		m_变换矩阵->f_unmap();

		return mat;
	}

	C_Mat44 mat = C_Mat44::kIdentity;
	auto rx = f_构建旋转矩阵(m_变换.rotation.x, E_轴向::e_X);
	auto ry = f_构建旋转矩阵(m_变换.rotation.y, E_轴向::e_Y);
	auto rz = f_构建旋转矩阵(m_变换.rotation.z, E_轴向::e_Z);
	auto s = f_构建缩放矩阵(m_变换.scale);

	mat *= f_构建移动矩阵(m_变换.location);
	//mat *= r;
	mat *= rz;
	mat *= ry;
	mat *= rx;

	mat *= s;
	return { mat };
}*/

/*if (m_是否实例) {
	f_buf_Mat44_at(m_父物体->m_变换矩阵, m_变换ID) = *mat;
	//f_copy板载缓存array((S_板载缓存*)(m_父物体->m_变换矩阵), m_实例ID, mat, 1);
}
else {
	f_copy板载缓存array((S_板载缓存*)(m_变换矩阵), m_实例ID, mat, 1);
}*/
/*if (m_是否实例) {
	f_copy板载缓存array((S_板载缓存*)(m_父物体->m_变换矩阵), m_实例ID, mat, 1);
}
else {
	f_copy板载缓存array((S_板载缓存*)(m_变换矩阵), m_实例ID, mat, 1);
}*/














